/*
 *  Workout.cpp
 *  Workout
 *
 *  Created by Acroname on 4/28/10.
 *  Copyright 2010 Acroname Robotics. All rights reserved.
 *
 */

#include "Workout.h"

////////////////////////////////////////////////////////////////////////////////

Workout::Workout(void) :
m_date(20100101),
m_time(600),
m_nExercises(0),
m_fPercentMax(1.0f),
m_settype(set5x5),
m_pCalcProc(calcSine),
m_pFilterProc(filterOlympic),
m_fCalcBasePercent(0.6f)
{
  sprintf(m_description, "UNDEF Workout");
}


////////////////////////////////////////////////////////////////////////////////


void 
Workout::AddExercise(ExerciseType e,
		     setType s,
		     int goalWeight,
		     const int time /* = 0 */,
		     weightCalcProc calcProc /* = calcFlat */,
		     exerciseFilterProc exFilter /* = filterNothing */,
		     bool optional /* = false */,
		     float fBaseCalcPercent /* 0.6f */)
{
  
  // Might be setting it as optional
  m_exercise[m_nExercises].SetOptional(optional);
  
  // Calculate the goal weight based on workout percent of max
  float targetWeight = m_fPercentMax * (float) goalWeight;
  
  m_exercise[m_nExercises++].AddSetType(e, 
					s, 
					(int) targetWeight, 
					time,
					m_fPercentMax,
					calcProc, 
					exFilter,
					fBaseCalcPercent);
  
}

////////////////////////////////////////////////////////////////////////////////


void 
Workout::AddExercise(ExerciseType e,
		     const int sets,
		     const int *reps,
		     int goalWeight,
		     const int time /* = 0 */,
		     weightCalcProc calcProc /* = calcFlat */,
		     exerciseFilterProc exFilter /* = filterNothing */,
		     bool optional /* = false */,
		     float fBaseCalcPercent /* 0.6f */)
{
  
  // Might be setting it as optional
  m_exercise[m_nExercises].SetOptional(optional);
  
  // Calculate the goal weight based on workout percent of max
  float targetWeight = m_fPercentMax * (float) goalWeight;
  
  m_exercise[m_nExercises].SetType(e);
  
  m_exercise[m_nExercises++].AddSetTypeParams(sets, 
					      reps, 
					      (int) targetWeight, 
					      time, 
					      m_fPercentMax, 
					      calcProc, fBaseCalcPercent);
  
}



////////////////////////////////////////////////////////////////////////////////

const char *
Workout::WorkoutShowDetails(OutputType t, FILE *pFile /* = NULL */)
{
  char buffer[2000];
  
  // Grab the pointer to the buffer
  const char * pB;
  pB = buffer;
  
  ///////////////////////////////////////////////////////
  // Format the output for what we want!
  switch (t) {
    case OutputHTML:
      
      // Show the workout daily description
      fprintf(pFile, "<h2>"
	      "Description: %s"
	      "</h2>"
	      "\n", m_description);
      
      // Show the workout day's percent of max goal
      fprintf(pFile, "<h3>"
	      "percent of max: %1.0f"
	      "</h3>"
	      "\n", m_fPercentMax * 100.0f);
      
      // Show the workout scheduled date
      fprintf(pFile, "<h4>"
	      "Date: %s"
	      " %d,"
	      " %d"
	      "</h4>"
	      "\n", 
	      GetCalendarDateMonth(m_date),
	      GetCalendarDateDay(m_date),
	      GetCalendarDateYear(m_date));
      
      // Create a numbered list
      fprintf(pFile, "<OL>");
      
      // Get all the exercises
      for (int j = 0; j < m_nExercises; j++) {
	
	// Get the exercise description
	fprintf(pFile, "<LI>"
		"%s %s"
		"</LI>",
		m_exercise[j].GetOptional() ? "(Optional): " : "",
		m_exercise[j].GetDescription()
		);
	
	fprintf(pFile, "<UL>");
	
	// Grab the number of sets
	for (int i = 0; i <= m_exercise[j].GetNumberOfSetsConsolidated(); i++) {
	  
	  // format the running if we need to
	  if (filterRunning(m_exercise[j].GetType())) {
	    fprintf(pFile, 
		    "<LI>"
		    "%d x %1.2f miles"
		    " [%1.0f m]",
		    m_exercise[j].GetSetReps(i),
		    RUNNING_CONV_FT2MILES(m_exercise[j].GetSetWeight(i)),
		    RUNNING_CONV_FT2METERS(m_exercise[j].GetSetWeight(i)));
	  }
	  else if (filterCore(m_exercise[j].GetType()) || filterBodyWeight(m_exercise[j].GetType())) {
	    fprintf(pFile, 
		    "<LI>"
		    "%d repititions ",
		    m_exercise[j].GetSetReps(i));
	  }
	  else if (filterClimbing(m_exercise[j].GetType())) {
	    fprintf(pFile, 
		    "<LI>"
		    "%d x %s ",
		    m_exercise[j].GetSetReps(i),
		    getClimbingGrade(m_exercise[j].GetSetWeight(i)));
	  }
	  else {
	    fprintf(pFile, 
		    "<LI>"
		    "%d x %d [%1.0f kg] ",
		    m_exercise[j].GetSetReps(i), 
		    m_exercise[j].GetSetWeight(i),
		    m_exercise[j].GetSetWeight(i) / 2.204f);
	  }
	  
	  if (m_exercise[j].GetSetRounds(i) > 1)
	    fprintf(pFile, 
		    "(x%d)\n", 
		    m_exercise[j].GetSetRounds(i));
	  
	  fprintf(pFile, "</LI>");
	  
	  
	} // end for loop for walking through sets
	
	fprintf(pFile, "</UL>\n");
	
      } // end for loop for exercises
      
      fprintf(pFile, "</OL>\n");
      
      break;
      
    case OutputDebug:
      
      // Show the workout daily description
      fprintf(pFile,"Description: %s"
	      "\n", m_description);
      
      // Show the workout day's percent of max goal
      fprintf(pFile,
	      "percent of max: %1.0f"
	      "\n", m_fPercentMax * 100.0f);
      
      // Show the workout scheduled date
      fprintf(pFile,
	      "Date: %s"
	      " %d,"
	      " %d"
	      "\n", 
	      GetCalendarDateMonth(m_date),
	      GetCalendarDateDay(m_date),
	      GetCalendarDateYear(m_date));
      
      // Get all the exercises
      for (int j = 0; j < m_nExercises; j++) {
	
	// Get the exercise description
	fprintf(pFile,
		"%s %s: ",
		m_exercise[j].GetOptional() ? "(Optional): " : "",
		m_exercise[j].GetDescription()
		);
	fprintf(pFile,"\n");
	
	
	// Grab the number of sets
	for (int i = 0; i <= m_exercise[j].GetNumberOfSetsConsolidated(); i++) {
	  
	  // format the running if we need to
	  if (filterRunning(m_exercise[j].GetType())) {
	    
	    if (m_exercise[j].GetSetReps(i) > 1) {
	      fprintf(pFile, 
		      "  %d x %1.2f miles",
		      m_exercise[j].GetSetReps(i),
		      RUNNING_CONV_FT2MILES(m_exercise[j].GetSetWeight(i)));
	    }
	    else {
	      fprintf(pFile, 
		      "  %1.2f miles",
		      RUNNING_CONV_FT2MILES(m_exercise[j].GetSetWeight(i)));
	    }
	    
	  }
	  else if (filterCore(m_exercise[j].GetType())) {
	    fprintf(pFile, 
		    "  %d repititions",
		    m_exercise[j].GetSetReps(i));
	  }
	  else {
	    fprintf(pFile, 
		    "  %d x %d [%1.0f kg]",
		    m_exercise[j].GetSetReps(i), 
		    m_exercise[j].GetSetWeight(i),
		    m_exercise[j].GetSetWeight(i) / 2.204f);
	  }
	  
	  if (m_exercise[j].GetSetRounds(i) > 1)
	    fprintf(pFile, 
		    "(x%d)\n", 
		    m_exercise[j].GetSetRounds(i));
	  else {
	    fprintf(pFile,"\n");
	  }
	  
	  
	  
	  
	} // end for loop for walking through sets
	
	
      } // end for loop for exercises
      
      
      break;
      
    case OutputICAL:
      
      // begin the event
      fprintf(pFile,"BEGIN:VEVENT\n");
      
      // Get the workout date and time
      fprintf(pFile,"DTSTART;TZID=America/Denver:");
      fprintf(pFile,"%i",m_date);
      fprintf(pFile,"T060000\n");
      fprintf(pFile,"DTEND;TZID=America/Denver:");
      fprintf(pFile,"%i",m_date);
      fprintf(pFile,"T080000\n");		
      fprintf(pFile,"SUMMARY:Workout \"%s\"\n", m_description);
      fprintf(pFile,"DESCRIPTION:");    
			
			// Show the workout day's percent of max goal
      fprintf(pFile, "Percent of max: %1.0f"
							"\\n", m_fPercentMax * 100.0f);
      
      
      // Get all the exercises
      for (int j = 0; j < m_nExercises; j++) {
	
	// Get the exercise description
	fprintf(pFile,
		"%s %s: \\n",
		m_exercise[j].GetOptional() ? "(Optional): " : "",
		m_exercise[j].GetDescription()
		);
	
	
	// Grab the number of sets
	for (int i = 0; i <= m_exercise[j].GetNumberOfSetsConsolidated(); i++) {
	  
	  // format the running if we need to
	  if (filterRunning(m_exercise[j].GetType())) {
	    
	    if (m_exercise[j].GetSetReps(i) > 1) {
	      fprintf(pFile, 
		      "  %d x %1.2f miles",
		      m_exercise[j].GetSetReps(i),
		      RUNNING_CONV_FT2MILES(m_exercise[j].GetSetWeight(i)));
	    }
	    else {
	      fprintf(pFile, 
		      "  %1.2f miles",
		      RUNNING_CONV_FT2MILES(m_exercise[j].GetSetWeight(i)));
	    }
	    
	  }
	  else if (filterCore(m_exercise[j].GetType()) || filterBodyWeight(m_exercise[j].GetType())) {
	    fprintf(pFile, 
		    "  %d repititions",
		    m_exercise[j].GetSetReps(i));
	  }
	  else if (filterClimbing(m_exercise[j].GetType())) {
	    fprintf(pFile, 
		    "  %d x %s ",
		    m_exercise[j].GetSetReps(i),
		    getClimbingGrade(m_exercise[j].GetSetWeight(i)));
	  }
	  else {
	    fprintf(pFile, 
		    "  %d x %d [%1.0f kg] ",
		    m_exercise[j].GetSetReps(i), 
		    m_exercise[j].GetSetWeight(i),
		    m_exercise[j].GetSetWeight(i) / 2.204f);
	  }
	  
	  if (m_exercise[j].GetSetRounds(i) > 1)
	    fprintf(pFile, 
		    "(x%d)\\n", 
		    m_exercise[j].GetSetRounds(i));
	  else {
	    fprintf(pFile,"\\n");
	  }
	  
	  
	} // end for loop for walking through sets
      } // end for loop for exercises
      
      fprintf(pFile,"\n");
      fprintf(pFile,"END:VEVENT\n");
      
      
      break;
      
      
    default:
      break;
  }
  
  
  return pB;
}

